#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "strset.h"

#define T Strset_T


struct T{
    struct node{
            struct node *left;
            struct node *right;
            char str[256];
            } *node;
};

struct node *newNode(char *str)
{
	struct node* tnode = (struct node*) malloc( sizeof(struct node) );
	strcpy(tnode->str, str);
	tnode->left=NULL;
	tnode->right=NULL;
	return (tnode);
}

T Strset_new(void)
{ 
    T set = calloc(1, sizeof *set);
    assert(set);
    return set;
}

void bz_free(struct node* node)
{
    if(node == NULL) return;
    if((node->left == NULL)&&(node->right == NULL))
    {
        free(node);
        node = NULL;
    } else
    {
        bz_free(node->left);
        bz_free(node->right);
        node = NULL;
    }
}

void Strset_free(T *set)
{
    if(set == NULL) return;
    bz_free((*set)->node);
    free(set);
}

struct node* insert(struct node* node, char *str)
{
    if(node == NULL)
	{
             return (newNode(str));
	} else
	{
	    if(strcmp(str, node->str) < 0) node->left = insert(node->left, str);
	    else if(strcmp(str, node->str) > 0) node->right = insert(node->right, str);
	    return (node);
	}
}

void Strset_add(T set, char *str)
{
    set->node = insert(set->node, str);
}

int nz_count(struct node* node)
{
    if(node == NULL)
    {
            return 0;
    } else
    {
            return(1 + nz_count(node->left) + nz_count(node->right));
    }
}

void Strset_foreach(T set, void apply(char *str, void *cl), void *cl)
{
    assert(set);
    assert(apply);
    int *cnt;
    cnt = (int*)cl;
    int mnt = nz_count(set->node);
    *cnt = mnt;
}
